package com.qiwenshare.stock.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;

import org.apache.ibatis.annotations.Param;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiwenshare.stock.api.IStockDIService;
import com.qiwenshare.stock.common.HttpsUtils;
import com.qiwenshare.stock.domain.StockBean;
import com.qiwenshare.stock.domain.StockDayInfo;
import com.qiwenshare.stock.domain.StockHotgroupBean;
import com.qiwenshare.stock.domain.ZtStockBean;
import com.qiwenshare.stock.mapper.StockMapper;

import cn.hutool.core.bean.BeanUtil;

@Service
public class StockService extends ServiceImpl<StockMapper, StockBean> implements IStockDIService {

    private static final Logger logger = LoggerFactory.getLogger(StockService.class);
    public static ExecutorService executor = Executors.newFixedThreadPool(50);
    @Resource
    StockMapper stockMapper;

    @Override
    public void createStockInfoTable(String stockNum) {
        stockMapper.createStockDayInfoTable("stockdayinfo_" + stockNum);
        stockMapper.createStockWeekInfoTable("stockweekinfo_" + stockNum);
        stockMapper.createStockMonthInfoTable("stockmonthinfo_" + stockNum);
        stockMapper.createStockTimeInfoTable("stocktimeinfo_" + stockNum);
    }


    @Override
    public void insertStockList(List<StockBean> stockBeanList) {
        stockMapper.insertStockList(stockBeanList);
    }

    @Override
    public List<StockBean> selectStockList(@Param("key") String key, @Param("beginCount") Long beginCount, @Param("pageCount") Long pageCount) {
//        TableQueryBean miniuiTablePageQuery = MiniuiUtil.getMiniuiTablePageQuery(miniuiTableQueryBean);
        return stockMapper.selectStockList(key, beginCount, pageCount);
    }


    @Override
    public int getStockCount(String key, Long beginCount, Long pageCount) {
        return stockMapper.getStockCount(key, beginCount, pageCount);
    }

    @Override
    public List<StockBean> selectTotalStockList() {
        return stockMapper.selectTotalStockList();
    }

    @Override
    public StockBean getStockInfoById(String stockId) {
        return stockMapper.getStockInfoById(stockId);
    }

    @Override
    public List<StockBean> getNoExistStockList(List<StockBean> stockBeanList) {
        List<StockBean> stockList = selectTotalStockList();
        List<StockBean> newStock = new ArrayList<StockBean>();
        for (int i = 0; i < stockBeanList.size(); i++) {
            if (!stockList.contains(stockBeanList.get(i))) {
                newStock.add(stockBeanList.get(i));
            }
        }
        return newStock;
    }


    public JSONObject getStockShare(String stockCode) {
        System.out.println("正在获取股票编号：" + stockCode);
        String url = "http://query.sse.com.cn/commonQuery.do";
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("isPagination", "false");
        param.put("sqlId", "COMMON_SSE_CP_GPLB_GPGK_GBJG_C");
        param.put("companyCode", stockCode);
        String sendResult = HttpsUtils.doGetString(url, param);
        JSONArray result = null;
        try {
            result = JSONObject.parseObject(sendResult).getJSONArray("result");
        } catch (Exception e) {
            logger.error("com.alibaba.fastjson.JSONException: scan null error:{}" + e);
        }

        if (result == null || result.size() == 0) {
            return new JSONObject();
        }
        return result.getJSONObject(0);
    }


    @Override
    public List<StockBean> getStockListByScript() {
    	// 78
        String url = "http://19.push2.eastmoney.com/api/qt/clist/get";

        List<StockBean> stockBeanList = new ArrayList<StockBean>();

        Map<String, Object> param = new HashMap<String, Object>();
        param.put("pn", "1");
        param.put("pz", "3000");
        param.put("po", "1");
        param.put("np", "1");
        param.put("ut", "bd1d9ddb04089700cf9c27f6f7426281");
        param.put("fltt", "2");
        param.put("invt", "2");
        param.put("fid", "f3");
        param.put("fs", "m:1+t:2,m:1+t:23");
        param.put("fields", "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f26,f38,f39,f22,f11,f62,f128,f136,f115,f152,f297");
        param.put("invt", "2");
        param.put("invt", "2");
        param.put("invt", "2");
        String sendResult = HttpsUtils.doGetString(url, param);

        JSONObject data = new JSONObject();
        try {
            data = JSONObject.parseObject(sendResult).getJSONObject("data");
        } catch (JSONException e) {
            logger.error("解析jsonb报错：" + data.toJSONString());
        } catch (NullPointerException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }

        JSONArray diff = data.getJSONArray("diff");
        for (Object o : diff) {
            Map<String, Object> map = (Map) o;
            StockBean stockBean = new StockBean();
            stockBean.setStockNum((String) map.get("f12"));
            stockBean.setStockName((String) map.get("f14"));
            stockBean.setTotalFlowShares(objectToBigDecimal(map.get("f39")));
            stockBean.setTotalShares(objectToBigDecimal(map.get("f38")));
            stockBean.setUpDownRange(objectToBigDecimal(map.get("f3")));
            stockBean.setTurnOverrate(objectToBigDecimal(map.get("f8")));
            stockBean.setUpDownPrices(objectToBigDecimal(map.get("f4")));
            stockBean.setOpen(objectToBigDecimal(map.get("f17")));
            stockBean.setClose(objectToBigDecimal(map.get("f2")));
            stockBean.setHigh(objectToBigDecimal(map.get("f15")));
            stockBean.setLow(objectToBigDecimal(map.get("f16")));
            stockBean.setPreClose(objectToBigDecimal(map.get("f18")));
            stockBean.setVolume(objectToBigDecimal(map.get("f5")));
            stockBean.setAmount(objectToBigDecimal(map.get("f6")));
            stockBean.setAmplitude(objectToBigDecimal(map.get("f7")));
            stockBean.setTotalMarketValue(objectToBigDecimal( map.get("f20")));
            stockBean.setFlowMarketValue(objectToBigDecimal(map.get("f21")));
            stockBean.setListingDate(String.valueOf(map.get("f26")));

            stockBeanList.add(stockBean);
        }

        return stockBeanList;
    }
    
    
    // stock_list_url='http://66.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112408511497985758365_1642161610438&pn={}&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:80&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1642161610439'
    
    
//    https://37.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112409652956258733552_1699951705339
//    &pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281
//    &fltt=2&invt=2&wbp2u=7154094213573018|0|1|0|web&fid=f3&fs=m:0+t:6,m:0+t:80
//    &fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1699951705340
    
    
    public String szseStock() {
    	// 定义文件路径
        String filePath = "d:/37.txt";

        // 创建一个文件对象
        File file = new File(filePath);
    	 String line="";
    	try {
            // 创建文件读取器
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);

           
            // 逐行读取文件内容
            while ((line = bufferedReader.readLine()) != null) {
                // 处理每一行的内容
                System.out.println(line);
            }

            // 关闭文件读取器
            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    	return line;
    }
    
    public String urlStr(String url) {
		String str = "";
		try {
			str = url.replaceAll("\"", "%22");
			str = str.replaceAll("<", "%3C");
			str = str.replaceAll(">", "%3E");
			str = str.replaceAll(" ", "%20");
		} catch (Exception e) {
			logger.error("Url转义出错！");
		}
		return str;
	};
	
    @Override
    public List<StockBean> getSzseStockListByScript() {
        String url = "https://37.push2.eastmoney.com/api/qt/clist/get";
        List<StockBean> stockBeanList = new ArrayList<StockBean>();

        Map<String, Object> param = new HashMap<String, Object>();
        param.put("pn", "1");
        param.put("pz", "3000");
        param.put("po", "1");
        param.put("np", "1");
        param.put("ut", "bd1d9ddb04089700cf9c27f6f7426281");
        param.put("fltt", "2");
        param.put("invt", "2");
//        param.put("wbp2u", "7154094213573018|0|1|0|web");
        param.put("fid", "f3");
        param.put("fs", "m:0+t:6,m:0+t:80");
        param.put("fields", "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152");
//        param.put("invt", "2");
//        param.put("invt", "2");
//        param.put("invt", "2");
        String sendResult = HttpsUtils.doGetString(url, param);
//        String sendUrl = urlStr("https://37.push2.eastmoney.com/api/qt/clist/get?pn=1&pz=3000&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=7154094213573018|0|1|0|web&fid=f3&fs=m:0+t:6,m:0+t:80&fieds=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1699951705340");
//        String sendResult = HttpsUtils.doGetString(sendUrl);
        
//        String sendResult= szseStock();
//        System.out.println("sendResult===>" + sendResult);

        JSONObject data = new JSONObject();
        try {
            data = JSONObject.parseObject(sendResult).getJSONObject("data");
        } catch (JSONException e) {
            logger.error("解析jsonb报错：" + data.toJSONString());
        } catch (NullPointerException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }

        JSONArray diff = data.getJSONArray("diff");
        for (Object o : diff) {
            Map<String, Object> map = (Map) o;
            StockBean stockBean = new StockBean();
            stockBean.setStockNum((String) map.get("f12"));
            stockBean.setStockName((String) map.get("f14"));
//            stockBean.setTotalFlowShares(objectToBigDecimal(map.get("f39")));
//            stockBean.setTotalShares(objectToBigDecimal(map.get("f38")));
            stockBean.setUpDownRange(objectToBigDecimal(map.get("f3")));
            stockBean.setTurnOverrate(objectToBigDecimal(map.get("f8")));
            stockBean.setUpDownPrices(objectToBigDecimal(map.get("f4")));
            stockBean.setOpen(objectToBigDecimal(map.get("f17")));
            stockBean.setClose(objectToBigDecimal(map.get("f2")));
            stockBean.setHigh(objectToBigDecimal(map.get("f15")));
            stockBean.setLow(objectToBigDecimal(map.get("f16")));
            stockBean.setPreClose(objectToBigDecimal(map.get("f18")));
            stockBean.setVolume(objectToBigDecimal(map.get("f5")));
            stockBean.setAmount(objectToBigDecimal(map.get("f6")));
            stockBean.setAmplitude(objectToBigDecimal(map.get("f7")));
            stockBean.setTotalMarketValue(objectToBigDecimal( map.get("f20")));
            stockBean.setFlowMarketValue(objectToBigDecimal(map.get("f21")));
//            stockBean.setListingDate(String.valueOf(map.get("f26")));

            stockBeanList.add(stockBean);
        }

        return stockBeanList;
    }

    public Double objectToBigDecimal(Object o) {
        try {
            return Double.valueOf(String.valueOf(o));
        } catch (NumberFormatException e) {
            return Double.valueOf(0);
        }


    }


    @Override
    public void updateStock(StockBean stockBean) {
        stockMapper.updateById(stockBean);
    }

    @Override
    public StockBean getStockInfo(StockBean stockBean, List<StockDayInfo> stockdayinfoList) {
        StockBean currentStockBean = new StockBean();
        BeanUtil.copyProperties(stockBean, currentStockBean);
        int stockdayinfoListSize = stockdayinfoList.size();
        StockDayInfo currentStockdayinfo = stockdayinfoList.get(stockdayinfoListSize - 1);
        StockDayInfo preStockdayinfo = stockdayinfoList.get(stockdayinfoListSize - 1 - 1);
        StockDayInfo pre3Stockdayinfo = new StockDayInfo();
        StockDayInfo pre5Stockdayinfo = new StockDayInfo();
        if (stockdayinfoListSize >= 4) {
            pre3Stockdayinfo = stockdayinfoList.get(stockdayinfoListSize - 1 - 3);
        }
        if (stockdayinfoListSize >= 6) {
            pre5Stockdayinfo = stockdayinfoList.get(stockdayinfoListSize - 1 - 5);
        }

        double currentClosePrise = currentStockdayinfo.getClose();
        double currentVolume = currentStockdayinfo.getVolume();
        double currentTotalFlowShares = stockBean.getTotalFlowShares();
        double currentHigh = currentStockdayinfo.getHigh();
        double currentLow = currentStockdayinfo.getLow();
        double preClosePrise = preStockdayinfo.getClose();
        double pre3ClosePrise = pre3Stockdayinfo.getClose();
        double pre5ClosePrise = pre5Stockdayinfo.getClose();
        double upDownRange = 0;
        double upDownRange3 = 0;
        double upDownRange5 = 0;
        double turnOverrate = 0;
        if (currentTotalFlowShares == 0) {
            logger.error("currentTotalFlowShares is zero, stockBean : {}", JSON.toJSONString(stockBean));
        } else {
            turnOverrate = currentVolume * 100 / currentTotalFlowShares;
        }

        double upDownPrices = currentClosePrise - preClosePrise;
        String newDate = currentStockdayinfo.getDate();

        double amplitude = 0;
        if (currentClosePrise - preClosePrise != 0) {
            if (preClosePrise == 0) {
                logger.error("preClosePrise is zero, stockBean : {}", JSON.toJSONString(stockBean));
            } else {
                amplitude = (currentHigh - currentLow) / preClosePrise;
                upDownRange = (currentClosePrise - preClosePrise) / preClosePrise;
            }

        }
        if (currentClosePrise - pre3ClosePrise != 0) {
            if (pre3ClosePrise == 0) {
                logger.error("pre3ClosePrise is zero, stockBean : {}", JSON.toJSONString(stockBean));
            } else {
                upDownRange3 = (currentClosePrise - pre3ClosePrise) / pre3ClosePrise;
            }

        }
        if (currentClosePrise - pre5ClosePrise != 0) {
            if (pre5ClosePrise == 0) {
                logger.error("pre5ClosePrise is zero, stockBean : {}", JSON.toJSONString(stockBean));
            } else {
                upDownRange5 = (currentClosePrise - pre5ClosePrise) / pre5ClosePrise;
            }

        }

        currentStockBean.setUpDownRange(upDownRange);
        currentStockBean.setUpDownRange3(upDownRange3);
        currentStockBean.setUpDownRange5(upDownRange5);
        currentStockBean.setTurnOverrate(turnOverrate);
        currentStockBean.setUpDownPrices(upDownPrices);
        currentStockBean.setOpen(currentStockdayinfo.getOpen());
        currentStockBean.setClose(currentStockdayinfo.getClose());
        currentStockBean.setHigh(currentStockdayinfo.getHigh());
        currentStockBean.setLow(currentStockdayinfo.getLow());
        currentStockBean.setPreClose(preClosePrise);
        currentStockBean.setVolume(currentStockdayinfo.getVolume());
        currentStockBean.setAmount(currentStockdayinfo.getAmount());
        currentStockBean.setAmplitude(amplitude);
        currentStockBean.setTotalMarketValue(stockBean.getTotalShares() * currentClosePrise);
        currentStockBean.setFlowMarketValue(stockBean.getTotalFlowShares() * currentClosePrise);
        currentStockBean.setStockId(stockBean.getStockId());
        currentStockBean.setUpdateDate(newDate);

        return currentStockBean;
    }


	@Override
	public List<ZtStockBean> selectHyZtStockList(String key, Long beginCount, Long pageCount) {
		java.util.Date day=new Date();
		SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
		String recordDate = sdf.format(day);
		List<ZtStockBean> stockBeanList = stockMapper.selectHyZtStockList(key, beginCount, pageCount ,recordDate);
		return stockBeanList;
	}


	@Override
	public int getHyZtStockCount(String key, Long beginCount, Long pageCount) {
		java.util.Date day=new Date();
		SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
		String recordDate = sdf.format(day);
		 return stockMapper.getHyZtStockCount(key, beginCount, pageCount,recordDate);
	}


	@Override
	public int getHyGnZtStockCount(String key, Long beginCount, Long pageCount) {
		java.util.Date day=new Date();
		SimpleDateFormat sdf= new SimpleDateFormat("MMdd");
		String stockTableName = "stock_gnzt_" + sdf.format(day);
		return stockMapper.getHyGnZtStockCount(key, beginCount, pageCount,stockTableName);
	}


	@Override
	public List<StockBean> selectHyGnZtStockList(String key, Long beginCount, Long pageCount) {
		java.util.Date day=new Date();

		SimpleDateFormat sdf= new SimpleDateFormat("MMdd");
		String stockTableName = "stock_gnzt_" + sdf.format(day);
		
		List<StockBean> stockBeanList = stockMapper.selectHyGnZtStockList(key, beginCount, pageCount,stockTableName);
		for(int i=0;i<stockBeanList.size();i++) {
			StockBean stockBean = stockBeanList.get(i);
			Double amount = stockBean.getAmount();
			if(amount/100000000 >= 1) {
				DecimalFormat df = new DecimalFormat("0.00");
				String amountStr = df.format(amount/100000000);
				stockBean.setAmountStr(amountStr + "亿");
			} else {
				Double amountDouble = amount/10000;
				Integer amountInteger = (int) Math.round(amountDouble);
				stockBean.setAmountStr(String.valueOf(amountInteger) + "万");
			}
		}
		return stockBeanList;
	}


	@Override
	public List<StockHotgroupBean> getStockTableHotDataList() {
		// TODO Auto-generated method stub
		return stockMapper.getStockTableHotDataList();
	}


	@Override
	public List<ZtStockBean> importZtDataByBackEnd() {
		java.util.Date day=new Date();
		SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMdd");
		String importDate = sdf.format(day);
		String fileName = "zt" + importDate + ".xlsx";
		;
		List<ZtStockBean> ztStockBeanList = readExcel("E:/download/BaiduNetdiskDownload/简单复盘13.8/data/zt20231117x.xlsx","Sheet1",
				new SimpleDateFormat("yyyy-MM-dd").format(day));
		
		stockMapper.insertZtStockList(ztStockBeanList);
		return ztStockBeanList;
		
	}


	private List<ZtStockBean> readExcel(String excelPath,String sheetName,String recordDate) {
		 List<ZtStockBean> ztStockBeanList = new ArrayList<>();


		 InputStream in = null;
	        try {
	            File file = new File(excelPath);
	            in = new FileInputStream(file);
	            Workbook workbook = WorkbookFactory.create(in);
	            Sheet sheet = workbook.getSheet(sheetName);
	            Row firstRow = sheet.getRow(0);
	            int lastCellNum = firstRow.getLastCellNum();
	            String[] titles = new String[lastCellNum];
	            for (int i = 0; i < lastCellNum; i++) {
	                Cell cell = firstRow.getCell(i);
	                String title = cell.getStringCellValue();
	                titles[i] = title;
	            }
	            int lastRowNum = sheet.getLastRowNum();
	            for (int i = 1; i <= lastRowNum  ; i++) {
	                Row rowData = sheet.getRow(i);
//	                System.out.print("第"+i+"行数据：");
	                ZtStockBean ztStockBean = new ZtStockBean();
	                ztStockBean.setRecordDate(recordDate);
	                for (int j = 0; j < lastCellNum ; j++) {
	                    Cell cell = rowData.getCell(j);
	                    String cellValue = cell.getStringCellValue();
	                    // 打印获取到的值
//	                    System.out.print("【"+ titles[j] + "="+ cellValue+"】");
	                    
//	           		 第44行数据：【股票代码=300814】【=中富电路】【=1】【=高带宽存储器HBM+先进封装】【=40.88】【=19.99】【=10.71】
//	   				 【=40.61】【=20.77】【=71.87】【=2023/11/17 10:56:21】【=2023/11/17 10:56:21】【=0】【=】
//	   				 【=公司持有先进封装技术公司40%股权，市场称其具备先进封装技术储备】【=英伟达H200芯片HBM容量大幅提升】
	                    if(titles[j].equals("股票代码")) {
	                    	ztStockBean.setStockNum(cellValue);
	                    } 
	                    else if(titles[j].equals("股票名称")) {
	                    	ztStockBean.setStockName(cellValue);
	                    }
						else if(titles[j].equals("连板")) {
							ztStockBean.setLianban(cellValue);                    	
						}
						else if(titles[j].equals("涨停原因")) {
							ztStockBean.setZtReason(cellValue);
						}
						else if(titles[j].equals("涨停价")) {
							ztStockBean.setZtPrice(cellValue);
						}
						else if(titles[j].equals("涨幅%")) {
							ztStockBean.setZhangfu(cellValue);
						}
						else if(titles[j].equals("封单比%")) {
							ztStockBean.setFengdanbi(cellValue);
						}
						else if(titles[j].equals("换手率%")) {
							ztStockBean.setHuanshoulv(cellValue);
						}
						else if(titles[j].equals("总市值")) {
							ztStockBean.setZongshizhi(cellValue);
						}
						else if(titles[j].equals("首封")) {
							ztStockBean.setShoufeng(cellValue);
						}
						else if(titles[j].equals("封住")) {
							ztStockBean.setFengzhu(cellValue);
						}
						else if(titles[j].equals("开板")) {
							ztStockBean.setKaiban(cellValue);						
						}
						else if(titles[j].equals("几天几板")) {
							ztStockBean.setJitianjiban(cellValue);
						}
						else if(titles[j].equals("涨停分析")) {
							ztStockBean.setZhangtingfenxi(cellValue);
						}
						else if(titles[j].equals("热点分析")) {
							ztStockBean.setRedianfenxi(cellValue);
						}
						else {
							
						}
	                }
	                ztStockBeanList.add(ztStockBean);
//	                System.out.println();
	            }
	            
	        } catch (Exception e) {
	            e.printStackTrace();
	        } finally {
	            if (in!=null){
	                try {
	                    in.close();
	                } catch (IOException e) {
	                    e.printStackTrace();
	                }
	            }
	        }
	        
	        return ztStockBeanList;
	    }

}
